///////////////////////////////////////////////////////////////////////////////
//  2007-2013 Xilinx, Inc. All Rights Reserved.
// Confidential and proprietary information of Xilinx, Inc.
///////////////////////////////////////////////////////////////////////////////
//   ____  ____ 
//  /   /\/   / 
// /___/  \  /   Vendor: Xilinx 
// \   \   \/    Version: 1.0
//  \   \        Filename:  sata_phy_oob.v
//  /   /        Date Last Modified: Aug. 1st, 2013
// /___/   /\    Date Created: Aug. 1st, 2013
// \   \  /  \ 
//  \___\/\___\ 
//
// Device: All
// Purpose: SATA Host Phy OOB Initialization.
// Reference:  
// Revision History:
//   Rev 1.0 - First created, ZhangMengjie, Aug. 1st, 2013.
//   modify by lcp, only for simulate, some cases are not taken into consideration.
///////////////////////////////////////////////////////////////////////////////
`timescale 1ns / 1ps


/**************** Primitive Genarated by FIS Transmitter ****************/
`define	ALIGN			32'h7B4A4ABC		// D27.3/D10.2/D10.2/K28.5
`define	SYNC			32'hB5B5957C		// D21.5/D21.5/D21.4/K28.3
`define	CONT			32'h9999AA7C		// D25.4/D25.4/D10.5/K28.3
`define	X_RDY			32'h5757B57C		// D23.2/D23.2/D21.5/K28.3
`define	SOF				32'h3737B57C		// D23.1/D23.1/D21.5/K28.3
`define	EOF				32'hD5D5B57C		// D21.6/D21.6/D21.5/K28.3
`define	WTRM			32'h5858B57C		// D24.2/D24.2/D21.5/K28.3
`define	HOLDA			32'h9595AA7C		// D21.4/D21.4/D10.5/K28.3
`define	R_RDY			32'h4A4A957C		// D10.2/D10.2/D21.4/K28.3
`define	R_IP			32'h5555B57C		// D21.2/D21.2/D21.5/K28.3
`define	HOLD			32'hD5D5AA7C		// D21.6/D21.6/D21.5/K28.3
`define	R_OK			32'h3535B57C		// D21.1/D21.1/D21.5/K28.3
`define	R_ERR			32'h5656B57C		// D22.2/D22.2/D21.5/K28.3
`define	DMAT			32'h3636B57C		// D22.1/D22.1/D21.5/K28.3
/**************** Primitive Genarated by FIS Transmitter ****************/



module sata_phy_oob_device
	# (
		parameter	tDLY		= 0							// Simulation delay
	)                                                   	
	                                                    	
	(                                                   	
		// Phy Interface Clock and Reset                      	
		input					phy_clk,					// Phy Clock, Rising Edge
		input					sys_reset_n,				// System Reset, Low Active
		                                                	
		// Transmit Interface from Link Layer            	
		input		[3:0]		TXCHARISK_LNK,				// TXCHARISK is set High to send TXDATA as an 8B/10B K character
		input		[31:0]		TXDATA_LNK,					// The bus for transmitting data		                                                                                                     
		
		// SStatus Register Field
		output		[3:0]		DETECT,						// interface device detection and Phy state
		output		[3:0]		SPEED,						// negotiated interface communication speed established
		output		[3:0]		IPM,						// current interface power management state
		
		// SError Register Diagnostic Field
		output					PhyRdyChg,					// PHYRDY signal changed state
		output					COMWAKEDet,					// COMWAKE signal was detected by the Phy
		output					DecErr,						// one or more 10b to 8b decoding errors occurred
		output					DispErr,					// incorrect disparity was detected one or more times
		output					Exchanged,					// device presence has changed
		
		// SError Register Error Field
		output					RecoveredCommErr,			// Communications between the device and host was temporarily lost but was re-established
		
		output		[11:0]		phy_oob_tgd,		                                     		
		// SATA PHY Interface Specification             	
(* MARK_DEBUG ="true" *)		input					PHYRESET,					// This signal causes the Phy to initialize to a known state and start generating the COMRESET OOB signal            	
		output					PHYRDY0,					// Signal indicating Phy has successfully established communications
		output					PHYRDY1,					// Signal indicating Phy has successfully established communications
		output					PHYRDY2,					// Signal indicating Phy has successfully established communications
		output					PHYRDY3,					// Signal indicating Phy has successfully established communications
		output					PHYRDY4,					// Signal indicating Phy has successfully established communications
		output					PHYRDY5,					// Signal indicating Phy has successfully established communications
		output					PHYRDY6,					// Signal indicating Phy has successfully established communications
(* MARK_DEBUG ="true" *)		input					TXRESETDONE,				// This port goes High when the MGT TX has finished reset and is ready for use
(* MARK_DEBUG ="true" *)		input					RXRESETDONE,				// This port goes High when the MGT RX has finished reset and is ready for use
(* MARK_DEBUG ="true" *)		input					RXLOSSOFSYNC,				// 1: Sync lost due to either sequence of invalid characters or reset
		output		[3:0]		TXCHARISK,					// TXCHARISK is set High to send TXDATA as an 8B/10B K character
		output		[31:0]		TXDATA,						// The bus for transmitting data
		input		[3:0]		RXDISPERR,					// When High, RXDISPERR indicates that the corresponding byte of RXDATA has a disparity error
		input		[3:0]		RXNOTINTABLE,				// RXNOTINTABLE indicates that the corresponding byte of RXDATA was not a valid character in the 8B/10B table
		input		[3:0]		RXCHARISK,					// RXCHARISK indicates that the corresponding byte of RXDATA is a K character
		input		[31:0]		RXDATA,						// The bus for receiving data
		output					TXCOMINIT,					// This signal initiates the transmission of the TXCOMINIT sequence
		output					TXCOMWAKE,					// This signal initiates the transmission of the TXCOMWAKE sequence
		output					TXELECIDLE,					// When in SATA mode, keep TXELECIDLE High for generating SATA OOB COM signaling
		input					COMFINISH,					// This signal indicates completion of transmission of the last SATA TXCOM sequence
		input					COMINITDET,					// Indicates detection of a COMINIT sequence
(* MARK_DEBUG ="true" *)		input					COMWAKEDET,					// Indicates detection of a COMWAKE sequence
(* MARK_DEBUG ="true" *)		input					RXELECIDLE					// Signals below minimum threshold are OOB signals, 1: OOB signal detected
);




//---------------------------------------------------------------------
// registers
//---------------------------------------------------------------------
(* mark_debug="true" *)reg		[4:0]		phy_state;

// SStatus Register Field
reg		[3:0]		DETECT_r;					
reg		[3:0]		SPEED_r;					
reg		[3:0]		IPM_r;						
		
// SError Register Diagnostic Field
reg					PhyRdyChg_r;				
reg					COMWAKEDet_r;				
reg					DecErr_r;					
reg					DispErr_r;					
reg					Exchanged_r;				

// SError Register Error Field
reg					RecoveredCommErr_r;			
								
// SATA PHY Interface Specification     
reg					PHYRESET_r;					
reg					PHYRESET_r2;				
reg					PHYRESET_r3;				
reg					PHYRDY_r;					
reg					TXRESETDONE_r;				
reg					RXRESETDONE_r;				
reg					TXRESETDONE_r2;				
reg					RXRESETDONE_r2;				
reg					RXLOSSOFSYNC_r;				
reg		[3:0]		TXCHARISK_r;				
reg		[31:0]		TXDATA_r;					
reg		[3:0]		RXDISPERR_r;				
reg		[3:0]		RXNOTINTABLE_r;				
reg		[3:0]		RXCHARISK_r;				
reg		[31:0]		RXDATA_r;					
reg					TXCOMINIT_r;				
reg					TXCOMWAKE_r;				
reg					TXELECIDLE_r;				
reg					COMFINISH_r;				
reg					COMINITDET_r;				
reg					COMWAKEDET_r;				
reg					RXELECIDLE_r;				
reg					RXELECIDLE_r2;				

reg					dp_sel;				
reg					dev_det;					
reg		[7:0]		rst_dly_cnt;				
reg		[16:0]		ato_cnt;				
reg		[16:0]		sto_cnt;				
reg		[20:0]		to10_cnt;				
reg					ald_st;			
reg		[1:0]		cnt2b_0; 
reg		[1:0]		cnt2b_1;
reg		[1:0]		cnt2b_2;
reg		[2:0]		cnt3b;
reg		[4:0]		cnt5b;

reg		[1:0]		fb_align_cnt;
reg		[1:0]		fb_notAlign_cnt;

reg					PHYRDY_r2;
reg					PHYRDY_r3;
reg					PHYRDY_r4;
reg					PHYRDY_r5;
reg					PHYRDY_r6;
reg					PHYRDY_r7;
reg					PHYRDY_r8;
reg					PHYRDY_r9;
reg		[7:0]		llo_cnt;


//---------------------------------------------------------------------
// wires
//---------------------------------------------------------------------


	



//---------------------------------------------------------------------
// PHY_FSM state variable assignments (sequential coded) 
//---------------------------------------------------------------------
localparam phy_s0		= 4'b0000;
localparam phy_s1		= 4'b0001;
localparam phy_s2		= 4'b0010;
localparam phy_s3 		= 4'b0011;
localparam phy_s4 		= 4'b0100;
localparam phy_s5 		= 4'b0101;
localparam phy_s6 		= 4'b0110;
localparam phy_s7 		= 4'b0111;
localparam phy_s8 		= 4'b1000;
localparam phy_s9 		= 4'b1001;
localparam phy_s10 		= 4'b1010;
localparam phy_s11 		= 4'b1011;
localparam phy_s12 		= 4'b1100;

localparam wait_for_comreset  	= 5'b10001;
localparam fb_cominit 			= 5'b10010;
localparam fb_cominit_finish 	= 5'b10011;

localparam wait_for_comwake 	= 5'b10100;
localparam fb_comwake 			= 5'b10101;
localparam fb_comwake_finish 	= 5'b10110;

localparam fb_align 			= 5'b10111 ;
localparam wait_for_align 		= 5'b11000;
localparam fb_notAlign  		= 5'b11001;

localparam device_ready  		= 5'b11010;






// SStatus Register Field
assign	DETECT				= DETECT_r;
assign	SPEED				= SPEED_r;
assign	IPM					= IPM_r;
		
// SError Register Diagnostic Field
assign	PhyRdyChg			= PhyRdyChg_r;
assign	COMWAKEDet			= COMWAKEDet_r;
assign	DecErr				= DecErr_r;
assign	DispErr				= DispErr_r;
assign	Exchanged			= Exchanged_r;

// SError Register Error Field
assign	RecoveredCommErr	= RecoveredCommErr_r;
				                                     	
// SATA PHY Interface Specification          	
assign	PHYRDY0				= PHYRDY_r3;
assign	PHYRDY1				= PHYRDY_r4;
assign	PHYRDY2				= PHYRDY_r5;
assign	PHYRDY3				= PHYRDY_r6;
assign	PHYRDY4				= PHYRDY_r7;
assign	PHYRDY5				= PHYRDY_r8;
assign	PHYRDY6				= PHYRDY_r9;	        	
assign	TXCHARISK			= dp_sel ? TXCHARISK_LNK : TXCHARISK_r;
assign	TXDATA				= dp_sel ? TXDATA_LNK : TXDATA_r;
assign	TXCOMINIT			= TXCOMINIT_r;
assign	TXCOMWAKE			= TXCOMWAKE_r;
assign	TXELECIDLE			= TXELECIDLE_r;			
		
		
		





//---------------------------------------------------------------------
// Input Register
//---------------------------------------------------------------------
always@(posedge phy_clk, negedge sys_reset_n)
begin
	if (!sys_reset_n)
	begin
		// SATA PHY Interface Specification
		TXRESETDONE_r <= #tDLY 1'b0;
		RXRESETDONE_r <= #tDLY 1'b0;
		TXRESETDONE_r2 <= #tDLY 1'b0;
		RXRESETDONE_r2 <= #tDLY 1'b0;   
		PHYRESET_r <= #tDLY 1'b0;
		PHYRESET_r2 <= #tDLY 1'b0;
		PHYRESET_r3 <= #tDLY 1'b0;
		RXLOSSOFSYNC_r <= #tDLY 1'b0;
		COMFINISH_r <= #tDLY 1'b0;
		COMINITDET_r <= #tDLY 1'b0;
		COMWAKEDET_r <= #tDLY 1'b0;
		RXELECIDLE_r <= #tDLY 1'b0;
		RXELECIDLE_r2 <= #tDLY 1'b0;
	end
	else
	begin
		// SATA PHY Interface Specification
		TXRESETDONE_r <= #tDLY TXRESETDONE;
		RXRESETDONE_r <= #tDLY RXRESETDONE;
		TXRESETDONE_r2 <= #tDLY TXRESETDONE_r;
		RXRESETDONE_r2 <= #tDLY RXRESETDONE_r;   
		PHYRESET_r <= #tDLY PHYRESET;
		PHYRESET_r2 <= #tDLY PHYRESET_r;
		PHYRESET_r3 <= #tDLY PHYRESET_r2;
		RXLOSSOFSYNC_r <= #tDLY RXLOSSOFSYNC;
		COMFINISH_r <= #tDLY COMFINISH;
		COMINITDET_r <= #tDLY COMINITDET;
		COMWAKEDET_r <= #tDLY COMWAKEDET;
		RXELECIDLE_r <= #tDLY RXELECIDLE;
		RXELECIDLE_r2 <= #tDLY RXELECIDLE_r;
	end
end

always@(posedge phy_clk)
begin
	// SATA PHY Interface Specification
	RXDISPERR_r <= #tDLY RXDISPERR;
	RXNOTINTABLE_r <= #tDLY RXNOTINTABLE;
	RXCHARISK_r <= #tDLY RXCHARISK;
	RXDATA_r <= #tDLY RXDATA;
end

		






always@(posedge phy_clk, negedge sys_reset_n)
begin
	if (!sys_reset_n)
	begin
		phy_state <= #tDLY wait_for_comreset;
		
		// SError Register Diagnostic Field
		PhyRdyChg_r <= #tDLY 1'b0; 
		COMWAKEDet_r <= #tDLY 1'b0; 
		Exchanged_r <= #tDLY 1'b0;

		// SATA PHY Interface Specification  		
		PHYRDY_r <= #tDLY 1'b0;	
		TXCHARISK_r <= #tDLY 4'b0001;
		TXDATA_r <= #tDLY `ALIGN;
		TXCOMINIT_r <= #tDLY 1'b0;
		TXCOMWAKE_r <= #tDLY 1'b0; 
		TXELECIDLE_r <= #tDLY 1'b0;
		
		dev_det <= #tDLY 1'b0;
		dp_sel <= #tDLY 1'b0;
	end
	else
	begin
		case (phy_state)
			wait_for_comreset :				
			begin
				if (COMINITDET_r == 1)
				begin
					phy_state <= #tDLY fb_cominit;
				end
				
				// SError Register Diagnostic Field
				COMWAKEDet_r <= #tDLY 1'b0;
				
				// SATA PHY Interface Specification 		
				PHYRDY_r <= #tDLY 1'b0;	
				TXCHARISK_r <= #tDLY 4'b0001;
				TXDATA_r <= #tDLY `ALIGN;
				TXCOMINIT_r <= #tDLY 1'b0;
				TXCOMWAKE_r <= #tDLY 1'b0; 
				TXELECIDLE_r <= #tDLY 1'b1;
				
				dev_det <= #tDLY 1'b0; 
				dp_sel <= #tDLY 1'b0;
			end
			
			fb_cominit :					
			begin
				phy_state <= #tDLY fb_cominit_finish;
				
				// SError Register Diagnostic Field
				PhyRdyChg_r <= #tDLY 1'b0; 
				COMWAKEDet_r <= #tDLY 1'b0; 
				Exchanged_r <= #tDLY 1'b0;
				
				// SATA PHY Interface Specification  		
				PHYRDY_r <= #tDLY 1'b0;
				TXCOMINIT_r <= #tDLY 1'b1;
				TXCOMWAKE_r <= #tDLY 1'b0; 
				TXELECIDLE_r <= #tDLY 1'b1;
			end
			
			fb_cominit_finish :				
			begin
				if (COMFINISH_r)					
				begin
					phy_state <= #tDLY wait_for_comwake;
				end
				
				// SATA PHY Interface Specification  		
				PHYRDY_r <= #tDLY 1'b0;
				TXCOMINIT_r <= #tDLY 1'b0;
				TXCOMWAKE_r <= #tDLY 1'b0; 
				TXELECIDLE_r <= #tDLY 1'b1;
			end
			
			wait_for_comwake :			
			begin
				if (COMWAKEDET_r)					
				begin
					phy_state <= #tDLY fb_comwake;
				end
				// else if (to10_cnt == 21'h1FFFFF)	
				// begin
					// phy_state <= #tDLY phy_s0;
				// end
				
				// SATA PHY Interface Specification  		
				TXCOMINIT_r <= #tDLY 1'b0;
				TXCOMWAKE_r <= #tDLY 1'b0; 
				TXELECIDLE_r <= #tDLY 1'b1;
			end
			
			fb_comwake :			
			begin
				phy_state <= #tDLY fb_comwake_finish;
				
				// SATA PHY Interface Specification	
				TXCOMINIT_r <= #tDLY 1'b0;
				TXCOMWAKE_r <= #tDLY 1'b1; 
				TXELECIDLE_r <= #tDLY 1'b1;
				
				dev_det <= #tDLY 1'b1;  			
			end
			
			fb_comwake_finish :			
			begin
				if (COMFINISH_r)					
				begin
					phy_state <= #tDLY fb_align;
				end
				
				// SATA PHY Interface Specification		
				TXCOMINIT_r <= #tDLY 1'b0;
				TXCOMWAKE_r <= #tDLY 1'b0; 
				TXELECIDLE_r <= #tDLY 1'b1;
			end
			
			fb_align :			
			begin
				if (fb_align_cnt == 3)					
				begin
					phy_state <= #tDLY wait_for_align ;
				end
				
				// else if (to10_cnt == 21'h1FFFFF)	
				// begin
					// phy_state <= #tDLY phy_s0;
				// end
				
				// SATA PHY Interface Specification	
				TXCHARISK_r <= #tDLY 4'b0001;
				TXDATA_r <= #tDLY `ALIGN;
				TXCOMINIT_r <= #tDLY 1'b0;
				TXCOMWAKE_r <= #tDLY 1'b0; 
				TXELECIDLE_r <= #tDLY 1'b0;
			end
			wait_for_align:
			begin
				if(cnt2b_0 == 3) 
				begin
					phy_state <= fb_notAlign;
				end 
			
			end 
			fb_notAlign  :			
			begin
				if (fb_notAlign_cnt == 3)				
				begin
					phy_state <= #500 device_ready  ;
				end 
				TXCHARISK_r <= #tDLY 4'b0001;
				TXDATA_r <= #tDLY `SYNC;
				
			end
			
			
			
			device_ready :					
			begin
				if (((!PHYRESET_r3) && PHYRESET_r2) || (cnt3b == 7) || (cnt2b_2 == 3))			
				begin
					phy_state <= #tDLY wait_for_comreset;
					
					// SError Register Diagnostic Field
					PhyRdyChg_r <= #tDLY 1'b1;
					Exchanged_r <= #tDLY 1'b1;
				end
				
				// SATA PHY Interface Specification  		
				PHYRDY_r <= #tDLY 1'b1;	
				TXCHARISK_r <= #tDLY 4'b0001;
				TXDATA_r <= #tDLY `SYNC;
				TXCOMINIT_r <= #tDLY 1'b0;
				TXCOMWAKE_r <= #tDLY 1'b0; 
				TXELECIDLE_r <= #tDLY 1'b0;
				
				dev_det <= #tDLY 1'b1;
				dp_sel <= #tDLY 1'b1;
			end
			
			default :
			begin
				phy_state <= #tDLY 'bx;
				
				// SError Register Diagnostic Field
				PhyRdyChg_r <= #tDLY 1'bx; 
				COMWAKEDet_r <= #tDLY 1'bx; 
				Exchanged_r <= #tDLY 1'bx;
				
				// SATA PHY Interface Specification 		
				PHYRDY_r <= #tDLY 1'bx;	
				TXCHARISK_r <= #tDLY 4'bxxxx;
				TXDATA_r <= #tDLY 32'hxxxxxxxx;
				TXCOMINIT_r <= #tDLY 1'bx;
				TXCOMWAKE_r <= #tDLY 1'bx; 
				TXELECIDLE_r <= #tDLY 1'bx;
				
				dev_det <= #tDLY 1'bx; 
				dp_sel <= #tDLY 1'bx;
			end
		endcase
	end
end


always@(posedge phy_clk, negedge sys_reset_n)
begin
	if (!sys_reset_n)
	begin
		rst_dly_cnt <= #tDLY 0;
		
		ald_st <= #tDLY 1'b0;
	end
	else
	begin
		if (((phy_state == phy_s0) && TXRESETDONE_r2 && RXRESETDONE_r2) || 
			(phy_state == phy_s7) || (phy_state == wait_for_align))
		begin
			rst_dly_cnt <= #tDLY rst_dly_cnt + 1'b1;
		end
		else
		begin
			rst_dly_cnt <= #tDLY 0;
		end
		
		if ((phy_state == wait_for_align) && (rst_dly_cnt == 127))
		begin
			ald_st <= #tDLY 1'b1;
		end
		else if (phy_state != wait_for_align)
		begin
			ald_st <= #tDLY 1'b0;
		end
	end
end


always@(posedge phy_clk)
begin
	if (phy_state == phy_s9)
	begin
		ato_cnt <= #tDLY ato_cnt + 1'b1;
	end
	else
	begin
		ato_cnt <= #tDLY 0;
	end
end


always@(posedge phy_clk)
begin
	if (phy_state == phy_s10)
	begin
		sto_cnt <= #tDLY sto_cnt + 1'b1;
	end
	else
	begin
		sto_cnt <= #tDLY 0;
	end
end


always@(posedge phy_clk)
begin
	if ((phy_state == phy_s3) || (phy_state == phy_s6) ||
		(phy_state == phy_s8) || (phy_state == phy_s11))
	begin
		to10_cnt <= #tDLY to10_cnt + 1'b1;
	end
	else
	begin
		to10_cnt <= #tDLY 0;
	end
end



//---------------------------------------------------------------------
// cnt2b Counter
//---------------------------------------------------------------------
always@(posedge phy_clk)
begin
	if ((phy_state == wait_for_align) && ald_st && 
		(RXDATA_r == `ALIGN) && (RXCHARISK_r == 1) && (RXNOTINTABLE_r == 0) && (RXDISPERR_r == 0))
	begin
		cnt2b_0 <= #tDLY cnt2b_0 + 1'b1;
	end
	else
	begin
		cnt2b_0 <= #tDLY 0;
	end
	
	if ((phy_state == phy_s10) && 
		(RXDATA_r[7:0] == 8'h7C) && (RXCHARISK_r == 1) && (RXNOTINTABLE_r == 0) && (RXDISPERR_r == 0))
	begin
		cnt2b_1 <= #tDLY cnt2b_1 + 1'b1;
	end
	else
	begin
		cnt2b_1 <= #tDLY 0;
	end
	
	if ((phy_state == phy_s11) && (!RXLOSSOFSYNC_r))
	begin
		cnt5b <= #tDLY cnt5b + 1'b1;
	end
	else
	begin
		cnt5b <= #tDLY 0;
	end
	
	if ((phy_state == device_ready) && RXELECIDLE_r2 && COMWAKEDET_r)		
	begin																
		cnt2b_2 <= #tDLY cnt2b_2 + 1'b1;
	end
	else
	begin
		cnt2b_2 <= #tDLY 0;
	end
	
	if ((phy_state == device_ready) && RXLOSSOFSYNC_r)	
	begin
		cnt3b <= #tDLY cnt3b + 1'b1;
	end
	else
	begin
		cnt3b <= #tDLY 0;
	end
	
	if(phy_state == fb_align)
	begin
		fb_align_cnt <= fb_align_cnt + 1;
	end
	else
	begin
		fb_align_cnt <= 0;
	end
	
	if(phy_state == fb_notAlign)
	begin
		fb_notAlign_cnt <= fb_notAlign_cnt + 1;
	end
	else
	begin
		fb_notAlign_cnt <= 0;
	end
	
end


always@(posedge phy_clk, negedge sys_reset_n)
begin
	if (!sys_reset_n)
	begin
		DecErr_r <= #tDLY 1'b0;
		
		DispErr_r <= #tDLY 1'b0;
		
		RecoveredCommErr_r <= #tDLY 1'b0;
		PHYRDY_r2 <= #tDLY 1'b0;
		PHYRDY_r3 <= #tDLY 1'b0;
		PHYRDY_r4 <= #tDLY 1'b0;
		PHYRDY_r5 <= #tDLY 1'b0;
		PHYRDY_r6 <= #tDLY 1'b0;
		PHYRDY_r7 <= #tDLY 1'b0;
		PHYRDY_r8 <= #tDLY 1'b0;
		PHYRDY_r9 <= #tDLY 1'b0;
		llo_cnt <= #tDLY 0;
	end
	else
	begin
		if (PHYRDY_r && (RXNOTINTABLE_r != 0))
		begin
			DecErr_r <= #tDLY 1'b1;
		end
		else
		begin
			DecErr_r <= #tDLY 1'b0;
		end
		
		if (PHYRDY_r && (RXDISPERR_r != 0))
		begin
			DispErr_r <= #tDLY 1'b1;
		end
		else
		begin
			DispErr_r <= #tDLY 1'b0;
		end
		
		PHYRDY_r2 <= #tDLY PHYRDY_r;
		PHYRDY_r3 <= #tDLY PHYRDY_r;
		PHYRDY_r4 <= #tDLY PHYRDY_r;
		PHYRDY_r5 <= #tDLY PHYRDY_r;
		PHYRDY_r6 <= #tDLY PHYRDY_r;
		PHYRDY_r7 <= #tDLY PHYRDY_r;
		PHYRDY_r8 <= #tDLY PHYRDY_r;
		PHYRDY_r9 <= #tDLY PHYRDY_r;
		
		if ((!PHYRDY_r2) && PHYRDY_r)
		begin
			llo_cnt <= #tDLY llo_cnt + 1'b1;
		end
		
		if ((!PHYRDY_r2) && PHYRDY_r && (llo_cnt != 0))
		begin
			RecoveredCommErr_r <= #tDLY 1'b1;
		end
		else
		begin
			RecoveredCommErr_r <= #tDLY 1'b0;
		end
	end
end


always@(posedge phy_clk)
begin
	if ((!dev_det) && (!PHYRDY_r))
	begin
		DETECT_r <= 0;
	end
	else if (dev_det && (!PHYRDY_r))
	begin
		DETECT_r <= 1;
	end
	else if (dev_det && PHYRDY_r)
	begin
		DETECT_r <= 3;
	end
	
	if (!PHYRDY_r)
	begin
		SPEED_r <= 0;
	end
	else
	begin
		SPEED_r <= 3;
	end
	
	if (!PHYRDY_r)
	begin
		IPM_r <= 0;
	end
	else
	begin
		IPM_r <= 1;
	end
end



assign	phy_oob_tgd[0]		= TXRESETDONE_r2;
assign	phy_oob_tgd[1]		= RXRESETDONE_r2;
assign	phy_oob_tgd[2]		= TXCOMINIT_r;
assign	phy_oob_tgd[3]		= TXCOMWAKE_r; 
assign	phy_oob_tgd[4]		= TXELECIDLE_r;
assign	phy_oob_tgd[5]		= COMFINISH_r;
assign	phy_oob_tgd[6]		= COMINITDET_r;
assign	phy_oob_tgd[7]		= COMWAKEDET_r;
assign	phy_oob_tgd[8]		= RXELECIDLE_r2;
assign	phy_oob_tgd[9]		= PHYRESET_r3;
assign	phy_oob_tgd[10]		= PHYRDY_r;
assign	phy_oob_tgd[11]		= RXLOSSOFSYNC_r;


endmodule
